package com.easylinkin.linkappapi.elasticsearch.util;/**
 * @Description
 * @ClassName Calendar
 * @Author 徐国庆
 * @date 2020.04.30 01:22
 */

import com.easylinkin.linkappapi.common.utils.DateUtil;
import org.springframework.util.Assert;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author xuguoqing
 * @version [V1.0, 2020年04月30日]
 * @Description:
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class EsCalendar {

  private static final String formatHMS = "yyyy-MM-dd HH:mm:ss";
  private static final String formatMon = "yyyy-MM";
  private static final String formatDay = "yyyy-MM-dd";
  private static final TimeZone curTimeZone = TimeZone.getTimeZone("GMT+8");
  private static final DateFormat dateFormatHMS = new SimpleDateFormat(formatHMS);
  private static final DateFormat dateformatMon = new SimpleDateFormat(formatMon);
  private static final DateFormat dateformatDay = new SimpleDateFormat(formatDay);

  //过去一天的凌晨零点
  public static String getStartTimeOfDay(int i) {
    Calendar calendar = Calendar.getInstance(curTimeZone);
    calendar.setTime(new Date());
    calendar.add(Calendar.HOUR_OF_DAY, -24 * i);
    calendar.set(java.util.Calendar.HOUR_OF_DAY, 0);
    calendar.set(java.util.Calendar.MINUTE, 0);
    calendar.set(java.util.Calendar.SECOND, 0);
    calendar.set(java.util.Calendar.MILLISECOND, 0);
    Date date = new Date(calendar.getTimeInMillis());
    System.out.println("过去一天时间1" + dateFormatHMS.format(date));
    return dateFormatHMS.format(date);
  }

  //当前时间
  public static String getCurerntTime() {
    Calendar calendar = Calendar.getInstance(curTimeZone);
    calendar.setTime(new Date());
    Date date = new Date(calendar.getTimeInMillis());
    return dateFormatHMS.format(date);
  }

  //一年以前的今天
  public static String getBefreYear() {
    Calendar calendar = Calendar.getInstance(curTimeZone);
    calendar.setTime(new Date());
    calendar.add(Calendar.YEAR, -1);
    calendar.set(java.util.Calendar.HOUR_OF_DAY, 0);
    calendar.set(java.util.Calendar.MINUTE, 0);
    calendar.set(java.util.Calendar.SECOND, 0);
    calendar.set(java.util.Calendar.MILLISECOND, 0);
    Date y = calendar.getTime();
    return dateFormatHMS.format(y);
  }

  //之前第几个月是几月
  public static String getBefreMonth(int i) {
    Calendar calendar = Calendar.getInstance(curTimeZone);
    calendar.setTime(new Date());
    calendar.add(Calendar.MONTH, -i);
    Date y = calendar.getTime();
    return dateformatMon.format(y);
  }

  public static String getBefreMonthByDate(Date date, int i) {
    Calendar calendar = Calendar.getInstance(curTimeZone);
    calendar.setTime(date);
    calendar.add(Calendar.MONTH, -i);
    Date y = calendar.getTime();
    return dateformatMon.format(y);
  }

  public static Date getBefreMonthfirstDayByDate(Date date, int i) throws ParseException {
    Calendar calendar = Calendar.getInstance(curTimeZone);
    calendar.setTime(date);
    calendar.add(Calendar.MONTH, -i);
    calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DATE));
    return dateformatDay.parse(dateformatDay.format(calendar.getTime()));
  }

  public static int getMonthDayByDate(Date date) {
    Calendar calendar = Calendar.getInstance(curTimeZone);
    calendar.setTime(date);
    return calendar.getActualMaximum(Calendar.DATE);
  }


  public static Date getBefreMonthLastDayByDate(Date date, int i) {
    Calendar calendar = Calendar.getInstance(curTimeZone);
    calendar.setTime(date);
    calendar.add(Calendar.MONTH, -i);
    calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
    return calendar.getTime();
  }


  //之前的第几天是何时
  public static String getBeforeDay(int i) {
    Calendar calendar = Calendar.getInstance(curTimeZone);
    calendar.setTime(new Date());
    calendar.add(Calendar.HOUR, -i * 24);
    Date y = calendar.getTime();
    return dateformatDay.format(y);
  }


  //之前的第几天是何时
  public static String getBeforeHmsDay(int i) {
    Calendar calendar = Calendar.getInstance(curTimeZone);
    calendar.setTime(new Date());
    calendar.add(Calendar.HOUR, -i * 24);
    calendar.set(java.util.Calendar.HOUR_OF_DAY, 0);
    calendar.set(java.util.Calendar.MINUTE, 0);
    calendar.set(java.util.Calendar.SECOND, 0);
    calendar.set(java.util.Calendar.MILLISECOND, 0);
    Date y = calendar.getTime();
    return dateFormatHMS.format(y);
  }


  //某一天之后的第几天
  public static String getAfterDayByDate(Date date, int i) {
    Calendar calendar = Calendar.getInstance(curTimeZone);
    calendar.setTime(date);
    calendar.add(Calendar.HOUR, i * 24);
    Date y = calendar.getTime();
    return dateFormatHMS.format(y);
  }


  //某一天之前的第几天
  public static String getBeforeDayByDate(Date date, int i) {
    Calendar calendar = Calendar.getInstance(curTimeZone);
    calendar.setTime(date);
    calendar.add(Calendar.HOUR, -i * 24);
    Date y = calendar.getTime();
    return dateformatDay.format(y);
  }

  public static Date getBeforeDayDateByDate(Date date, int i) throws ParseException {
    Calendar calendar = Calendar.getInstance(curTimeZone);
    calendar.setTime(date);
    calendar.add(Calendar.HOUR, -i * 24);
    return dateformatDay.parse(dateformatDay.format(calendar.getTime()));
  }


  //获取两个时间天的差距
  public static int getDiffDay(Date beginDate, Date endDate) throws ParseException {
    long beginTime = dateformatDay.parse(dateformatDay.format(beginDate)).getTime();
    long endTime = dateformatDay.parse(dateformatDay.format(endDate)).getTime();
    return (int) ((endTime - beginTime) / (1000 * 3600 * 24));
  }


  public static Date getDateByWeekCountAndWeekNumber(int weekCounts, int weekNumber)
      throws ParseException {
    Calendar calendar = Calendar.getInstance(curTimeZone);
    calendar.setTime(new Date());
    if (calendar.get(Calendar.DAY_OF_WEEK) != Calendar.SUNDAY) {
      if (weekNumber == Calendar.SUNDAY) {
        weekCounts++;
      }
    } else {
      if (weekNumber != Calendar.SUNDAY) {
        weekCounts--;
      }
    }
    calendar.add(Calendar.DATE, weekCounts * 7);
    calendar.set(Calendar.DAY_OF_WEEK, weekNumber);
    return dateformatDay.parse(dateformatDay.format(calendar.getTime()));
  }

  public static Map<String, Date> getDayOfLastWeek() {
    Map<String, Date> map = new HashMap<>();
    Calendar calendar = Calendar.getInstance();
    calendar.setFirstDayOfWeek(Calendar.MONDAY);
    int dayWeek = calendar.get(Calendar.DAY_OF_WEEK);// 获得当前日期是一个星期的第几天
    if (dayWeek == 1) {
      dayWeek = 8;
    }
    calendar.add(Calendar.DATE, calendar.getFirstDayOfWeek() - dayWeek);
    //周数减一，即上周
    calendar.add(Calendar.WEEK_OF_MONTH, -1);
    Date mondayDate = calendar.getTime();

    calendar.add(Calendar.DATE, 4 + calendar.getFirstDayOfWeek());
    Date sundayDate = calendar.getTime();

    map.put("mondayDate", mondayDate);
    map.put("sundayDate", sundayDate);

    return map;
  }

  public static Map<String, Date> getDayOfMonth() {
    Map<String, Date> map = new HashMap<>();
    Calendar calendar = Calendar.getInstance();
    calendar.add(Calendar.MONTH, 0);
    calendar.set(Calendar.DAY_OF_MONTH, 1);
    map.put("monthBegin", calendar.getTime());

    calendar = Calendar.getInstance();
    calendar.add(Calendar.MONTH, 1);
    calendar.set(Calendar.DAY_OF_MONTH, 0);
    map.put("monthEnd", calendar.getTime());
    return map;
  }

  public static String getyyyyMMddFromromDate(Date date) {

    return dateformatDay.format(date);

  }

  public static void main(String args[]) {
//    	String dateDay  = 	getBeforeHmsDay(1);
//    	dateDay  = 	getBeforeHmsDay(2);
//        System.out.println(getDeviceFlowIndex(0));
    System.out.println(getDeviceFlowIndex(1));
    System.out.println(getDeviceFlowIndex(2));
    System.out.println(getDeviceFlowIndex(6));
    System.out.println(getDeviceFlowIndex(12));

    System.out.println("11: "+getDeviceFlowIndex("2021-11-1 00:00:00", "2021-12-31 23:59:59"));
    System.out.println(getDeviceFlowIndex("2021-12-01 00:00:00", "2021-12-31 23:59:59"));
    System.out.println(getDeviceFlowIndex("2021-11-30 23:00:00", "2021-12-31 23:59:59"));
//        System.out.println(getDeviceFlowIndex("2022-11-30 23:00:00","2021-12-31 23:59:59"));
    System.out.println(getDeviceFlowIndex("2022-11-30 23:00:00", "2022-11-30 23:00:00"));
    System.out.println("55: "+getDeviceFlowIndex("2022-09-01 00:00:00", "2022-10-11 00:00:00"));
  }


  /**
   * @param monthCount 需要几个月的索引拼接
   * @return 索引拼接，1-代表只要本月的，2-代表要半年的
   */
  public static String getDeviceFlowIndex(int monthCount) {
    Assert.isTrue(monthCount > 0, "求取索引拼接，monthCount数量必须大于1");
    StringBuilder indices = new StringBuilder();
    for (int i = 0; i > -monthCount; i--) {
      indices.append(",").append("deviceflow-").append(DateUtil.getyyyyMM("yyyyMM", i));
    }
    return indices.substring(1);
  }

  /**
   * @param beginTime 开始时间
   * @param endTime   结束时间
   * @return 索引拼接，
   */
  public static String getDeviceFlowIndex(String beginTime, String endTime) {
    StringBuilder indices = new StringBuilder();
    Calendar cal1 = Calendar.getInstance();
    cal1.setTime(DateUtil.getDateFromYYYYMMDDHHmmss(beginTime));
    cal1.set(Calendar.DAY_OF_MONTH, 1);
    cal1.set(Calendar.HOUR_OF_DAY, 0);
    cal1.set(Calendar.MINUTE, 0);
    cal1.set(Calendar.SECOND, 0);
    cal1.set(Calendar.MILLISECOND, 0);
    Calendar cal2 = Calendar.getInstance();
    cal2.setTime(DateUtil.getDateFromYYYYMMDDHHmmss(endTime));
    cal2.set(Calendar.DAY_OF_MONTH, 1);
    cal2.set(Calendar.HOUR_OF_DAY, 0);
    cal2.set(Calendar.MINUTE, 0);
    cal2.set(Calendar.SECOND, 0);
    cal2.set(Calendar.MILLISECOND, 0);
    Assert.isTrue(cal1.compareTo(cal2) <= 0, "开始时间需小于结束时间。");
//    while (cal1.compareTo(cal2) <= 0) {
    while (DateUtil.getDateFromFormatStr(cal1.getTime(), "yyyy-MM").compareTo(DateUtil.getDateFromFormatStr(cal2.getTime(), "yyyy-MM")) <= 0) {
      indices.append(",").append("deviceflow-")
              .append(DateUtil.getDateFromFormatStr(cal1.getTime(), "yyyyMM"));
      cal1.add(Calendar.MONTH, 1);
    }
    return indices.substring(1);
  }

  /**
   * @param beginTime 开始时间
   * @param endTime   结束时间
   * @return 索引拼接，
   */
  public static String getDeviceFlowIndex(Date beginTime, Date endTime) {
    Assert.isTrue(beginTime.before(endTime),
        "开始时间" + cn.hutool.core.date.DateUtil.formatDate(beginTime) + "需小于结束时间"
            + cn.hutool.core.date.DateUtil.formatDate(endTime));

    StringJoiner sj = new StringJoiner(",");
    while (cn.hutool.core.date.DateUtil.beginOfMonth(beginTime).isBeforeOrEquals(
        cn.hutool.core.date.DateUtil.beginOfMonth(endTime))) {
      sj.add("deviceflow-" + cn.hutool.core.date.DateUtil.format(beginTime, "yyyyMM"));
      beginTime = cn.hutool.core.date.DateUtil.offsetMonth(beginTime, 1);
    }
    return sj.toString();
  }

}

